package com.stockz.scanner.screen;

import java.util.List;

import com.stockz.core.model.Bar;
import com.stockz.core.util.ListUtil;
import com.stockz.core.util.BarUtil.BarValueType;
import com.stockz.scanner.screen.configuration.ConsolidationBreakoutScreenConfiguration;

public class ConsolidationBreakoutScreen implements Screen<ConsolidationBreakoutScreenConfiguration> {

	private ConsolidationBreakoutScreenConfiguration configuration = 
			new ConsolidationBreakoutScreenConfiguration();
	
	@Override
	public ConsolidationBreakoutScreenConfiguration getConfiguration() {
		return configuration;
	}

	@Override
	public int getMandatorySpan() {
		return configuration.getConsolidationSpan()+configuration.getStandardDeviationSpan();
	}

	@Override
	public boolean isMatch(List<Bar> barList) {
		if(barList != null && barList.size() > configuration.getConsolidationSpan()+configuration.getStandardDeviationSpan()){
			return values(ListUtil.convert(barList, BarValueType.CLOSE),configuration);
		}
		return false;
	}
	
	public static boolean values(double[] barValues, ConsolidationBreakoutScreenConfiguration configuration){
		if(barValues != null){
			double sum = 0; 
			double sumSquared = 0;
			int span = configuration.getStandardDeviationSpan();
			double high = Double.MIN_VALUE;
			double value = 0;
			if(barValues.length > 0 && span > 1 && span <= barValues.length){
				for(int i = configuration.getConsolidationSpan() + span; i >=0; i--){
					if(barValues[i] == 0){
						continue;
					}
					if(i > configuration.getConsolidationSpan()){
						
					}else if(i ==  barValues.length - span){
						if(barValues[i] == 0){
							if(i == 0){
								value = Math.sqrt((span * sumSquared - (sum * sum))/ (span * (span- 1)))*100/barValues[1];
							}else{
								value = Math.sqrt((span * sumSquared - (sum * sum))/ (span * (span- 1)))*100/barValues[i-1];
							}
						}else{
							value = Math.sqrt((span * sumSquared - (sum * sum))/ (span * (span- 1)))*100/barValues[i];
						}
					}else{
						if(barValues[i] == 0){
							if(i == 0){
								value = Math.sqrt((span * sumSquared - (sum * sum))/ (span * (span- 1)))*100/barValues[1];
							}else{
								value = Math.sqrt((span * sumSquared - (sum * sum))/ (span * (span- 1)))*100/barValues[i-1];
							}
						}else{
							value = Math.sqrt((span * sumSquared - (sum * sum))/ (span * (span- 1)))*100/barValues[i];
						}			
						sum -= barValues[i+span];
						sumSquared -= (barValues[i+span]*barValues[i+span]);
					}
					if(i < configuration.getConsolidationSpan()){
						if(high < barValues[i]){
							high = barValues[i];
						}
						if(value > configuration.getConsolidationHeight() || barValues[0] < high){
							return false;
						}
					}
					sum += barValues[i];
					sumSquared += (barValues[i]*barValues[i]);
				}
			}
			return true;
		}
		return false;
	}

}
